package com.whut.utils;

import com.whut.v_vo.GroupPointVO;
import com.whut.v_vo.MeasureDataVO;
import com.whut.v_vo.PointVO;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author： wenyihan
 * @description：实测实量12中计算分类
 * @date： 12:45 2021/1/18
 * @return：
*/
public class NewMeasureTypeCalculationUtil {
    /**
     * 类型1
     * @description：2个实测1个设计值取偏差较大值计算合格情况
    */
    public static MeasureDataVO type1(List<GroupPointVO> groupPoints, String rangeMath){
        int totalPointNum = 0; //总点数
        int totalQFPointNum = 0; //总合格点数
        double qualifiedRate = 0.0d; //单项合格率
        boolean flag = false; //是否出现不合格点
        MeasureDataVO dataMap = new MeasureDataVO();
        for (GroupPointVO gp: groupPoints) {
            for (PointVO p: gp.getGroupData()) {
                //计算偏差值
                p.setDeviation(p.getMeasureValue() - gp.getDesignValue());
                boolean isQualified = RangeUtil.getRange(rangeMath).contains(p.getMeasureValue());
                if (!isQualified){
                    flag = true;
                }
            }
            //处理测量点：将其归类为合格点或者不合格点
            if (!flag){
                for (PointVO p: gp.getGroupData()) {
                    gp.getQFPoint().add(p.getMeasureValue());
                }
            }else{
                for (PointVO p: gp.getGroupData()) {
                    gp.getDQFPoint().add(p.getMeasureValue());
                }
            }
            //计算总点数
            totalPointNum += gp.getGroupData().size();
            //计算总合格点数
            totalQFPointNum += gp.getQFPoint().size();
        }
        dataMap.setGroupPoints(groupPoints);
        dataMap.setTotalPointNum(totalPointNum);
        dataMap.setTotalQFPointNum(totalQFPointNum);
        qualifiedRate = totalQFPointNum/totalPointNum;
        dataMap.setQualifiedRate(qualifiedRate);
        return dataMap;
    }

    /***
     * 类型二
     * @description：直接根据实测值计算合格情况
    */
    public static MeasureDataVO type2(List<GroupPointVO> groupPoints, String rangeMath){
        int totalPointNum = 0; //总点数
        int totalQFPointNum = 0; //总合格点数
        double qualifiedRate = 0.0d; //单项合格率
        MeasureDataVO dataMap = new MeasureDataVO();
        for (GroupPointVO gp: groupPoints){
            for (PointVO p: gp.getGroupData()) {
                //偏差值记为0
                p.setDeviation(0d);
                boolean isQualified = RangeUtil.getRange(rangeMath).contains(p.getMeasureValue());
                //将测量点分类
                if (isQualified){
                    gp.getQFPoint().add(p.getMeasureValue());
                }else{
                    gp.getDQFPoint().add(p.getMeasureValue());
                }
            }
            totalPointNum += gp.getGroupData().size();
            totalQFPointNum += gp.getQFPoint().size();
        }
        dataMap.setGroupPoints(groupPoints);
        dataMap.setTotalPointNum(totalPointNum);
        dataMap.setTotalQFPointNum(totalQFPointNum);
        qualifiedRate = totalQFPointNum/totalPointNum;
        dataMap.setQualifiedRate(qualifiedRate);
        return dataMap;
    }

    /**
     * 类型3
     * @description：实测5个值，取最小值为减数，与其他数的差值作为偏差值，若一组数据中有超过（规定标准）直接记为爆板，即全部不合格
    */
    public static MeasureDataVO type3(List<GroupPointVO> groupPoints, String rangeMath, String burstValue){
        int totalPointNum = 0; //总点数
        int totalQFPointNum = 0; //总合格点数
        double qualifiedRate = 0.0d; //单项合格率
        MeasureDataVO dataMap = new MeasureDataVO();
        String isBurst = "";

        //处理爆板值
        String regEx = "[^0-9]";
        Pattern pattern = Pattern.compile(regEx);
        Matcher m = pattern.matcher(burstValue);
        String str = m.replaceAll("").trim();
        double burstValueD = Math.abs(Double.valueOf(str));

        for (GroupPointVO gp: groupPoints) {
            //挑选最小值
            List<PointVO> groupDataList = gp.getGroupData();
            double minMeasurePoint = groupDataList.stream()
                                            .mapToDouble(PointVO -> PointVO.getMeasureValue())
                                            .min()
                                            .getAsDouble();
            for (PointVO p: gp.getGroupData()) {
                double deviation = p.getMeasureValue() - minMeasurePoint;
                p.setDeviation(deviation);
                boolean isQualified = RangeUtil.getRange(rangeMath).contains(deviation);
                if (deviation > burstValueD){
                    isBurst = "爆板";
                }else{
                    //在区间范围内记为合格点，超过区间但小于爆板值记为不合格，减数点为合格点
                    if (isQualified){
                        gp.getQFPoint().add(p.getMeasureValue());
                    }else{
                        gp.getDQFPoint().add(p.getMeasureValue());
                    }
                }
            }
            //如果超过爆板值，所有点记为不合格
            if (isBurst.equals("爆板")){
                for (PointVO p: gp.getGroupData()) {
                   gp.getDQFPoint().add(p.getMeasureValue());
                }
            }
            totalQFPointNum += gp.getQFPoint().size();
            totalPointNum += gp.getGroupData().size();
        }
        dataMap.setIsBurst(isBurst);
        dataMap.setGroupPoints(groupPoints);
        dataMap.setTotalPointNum(totalPointNum);
        dataMap.setTotalQFPointNum(totalQFPointNum);
        qualifiedRate = totalQFPointNum/totalPointNum;
        dataMap.setQualifiedRate(qualifiedRate);
        return dataMap;
    }

    /**
     * 类型4、5、6、9、11
     * @description：1个实测值1个设计值，相减计算合格情况；5个实测值，1个设计值，实测减去设计计算偏差值；2种实测值各测两次与对应2种设计值，相减计算合格情况，并整合计算合格率；
     * 1个实体，4种实测，其中高宽，各测2次实测值与对应设计值，相减计算偏差，另外两种直接对应偏差值，总计计算合格率；
     * 1个实测值，固定设计值。
    */
    public static MeasureDataVO type4And5And6(List<GroupPointVO> groupPoints, String rangeMath){
        int totalPointNum = 0; //总点数
        int totalQFPointNum = 0; //总合格点数
        double qualifiedRate = 0.0d; //单项合格率
        MeasureDataVO dataMap = new MeasureDataVO();
        for (GroupPointVO gp: groupPoints) {
            for (PointVO p: gp.getGroupData()) {
                //计算偏差值
                p.setDeviation(p.getMeasureValue() - gp.getDesignValue());

                //将点归类
                boolean isQualified = RangeUtil.getRange(rangeMath).contains(p.getDeviation());
                if (isQualified){
                    gp.getQFPoint().add(p.getMeasureValue());
                }else {
                    gp.getDQFPoint().add(p.getMeasureValue());
                }
            }
            totalPointNum += gp.getGroupData().size();
            totalQFPointNum += gp.getQFPoint().size();
        }
        qualifiedRate = totalQFPointNum/totalPointNum;
        dataMap.setGroupPoints(groupPoints);
        dataMap.setQualifiedRate(qualifiedRate);
        dataMap.setTotalPointNum(totalPointNum);
        dataMap.setTotalQFPointNum(totalQFPointNum);
        return dataMap;
    }

    /**
     * 类型7
     * @description：2个实测值取较大的值计算合格情况
    */
    public static MeasureDataVO type7(List<GroupPointVO> groupPoints, String rangeMath){
        int totalPointNum = 0; //总点数
        int totalQFPointNum = 0; //总合格点数
        double qualifiedRate = 0.0d; //单项合格率
        MeasureDataVO dataMap = new MeasureDataVO();
        for (GroupPointVO gp: groupPoints) {
            //获取两个实测值中最大值
            double maxMeasureValue = gp.getGroupData().stream()
                                                    .mapToDouble(PointVO::getMeasureValue)
                                                    .max()
                                                    .getAsDouble();
            boolean isQualified = RangeUtil.getRange(rangeMath).contains(maxMeasureValue);
            for (PointVO p: gp.getGroupData()){
                //不需要偏差值 记为0
                p.setDeviation(0d);
                //合格则全部合格，不合格则全部不合格
                if (isQualified){
                    gp.getQFPoint().add(p.getMeasureValue());
                }else {
                    gp.getDQFPoint().add(p.getMeasureValue());
                }
            }
            totalPointNum += gp.getGroupData().size();
            totalQFPointNum += gp.getQFPoint().size();
        }
        qualifiedRate = totalQFPointNum/totalPointNum;
        dataMap.setGroupPoints(groupPoints);
        dataMap.setQualifiedRate(qualifiedRate);
        dataMap.setTotalPointNum(totalPointNum);
        dataMap.setTotalQFPointNum(totalQFPointNum);
        return dataMap;
    }
    /**
     * 类型8
     * @description:2-3个实测值，取最小值为减数，与其他数的差值作为偏差值，若一组数据中有超过（规定标准），即全部不合格
     */
    public static MeasureDataVO type8(List<GroupPointVO> groupPoints, String rangeMath) {
        int totalPointNum = 0; //总点数
        int totalQFPointNum = 0; //总合格点数
        double qualifiedRate = 0.0d; //单项合格率
        MeasureDataVO dataMap = new MeasureDataVO();
        //isfailed记录是否出现不合格点
        boolean isfailed=false;
        for (GroupPointVO gp: groupPoints){
            //得到一组数据中的最小值
            List<PointVO> groupDataList = gp.getGroupData();
            double minMeasurePoint = groupDataList.stream()
                    .mapToDouble(PointVO -> PointVO.getMeasureValue())
                    .min()
                    .getAsDouble();
            //判断一组数据中是否存在不合格点，存在即跳出循环
            for (PointVO p: gp.getGroupData()) {
                double deviation = p.getMeasureValue() - minMeasurePoint;
                p.setDeviation(deviation);
                boolean isQualified = RangeUtil.getRange(rangeMath).contains(deviation);
                if (!isQualified){
                    isfailed=true;
                    break;
                }
            }
            //一组点存在不合格点，全部为不合格，否则为合格点
            if(isfailed){
                for (PointVO p: gp.getGroupData()) {
                    gp.getDQFPoint().add(p.getMeasureValue());
                }
            }else{
                for (PointVO p: gp.getGroupData()) {
                    gp.getQFPoint().add(p.getMeasureValue());
                }

            }
            //计算总点数
            totalPointNum += gp.getGroupData().size();
            //计算总合格点数
            totalQFPointNum += gp.getQFPoint().size();
        }
        qualifiedRate = totalQFPointNum/totalPointNum;
        dataMap.setGroupPoints(groupPoints);
        dataMap.setQualifiedRate(qualifiedRate);
        dataMap.setTotalPointNum(totalPointNum);
        dataMap.setTotalQFPointNum(totalQFPointNum);
        return dataMap;
    }
    /**
     * 类型10
     * @description:实测2个值，2个值相减计算偏差值
     */
    public static MeasureDataVO type10(List<GroupPointVO> groupPoints, String rangeMath){
        int totalPointNum = 0; //总点数
        int totalQFPointNum = 0; //总合格点数
        double qualifiedRate = 0.0d; //单项合格率
        MeasureDataVO dataMap = new MeasureDataVO();
        for(GroupPointVO gp:groupPoints) {
            List<PointVO> groupDataList = gp.getGroupData();
            double deviation =groupDataList.get(0).getMeasureValue()-groupDataList.get(1).getMeasureValue();
            boolean isQualified = RangeUtil.getRange(rangeMath).contains(deviation);
            for (PointVO p : gp.getGroupData()) {
                //保存偏差值
                p.setDeviation(deviation);
                if (isQualified){
                    gp.getQFPoint().add(p.getMeasureValue());
                }else {
                    gp.getDQFPoint().add(p.getMeasureValue());
                }
            }
            //计算总点数
            totalPointNum += gp.getGroupData().size();
            //计算总合格点数
            totalQFPointNum += gp.getQFPoint().size();
        }
        qualifiedRate = totalQFPointNum/totalPointNum;
        dataMap.setGroupPoints(groupPoints);
        dataMap.setQualifiedRate(qualifiedRate);
        dataMap.setTotalPointNum(totalPointNum);
        dataMap.setTotalQFPointNum(totalQFPointNum);
        return dataMap;
    }
    /**
     * 类型12
     * @description12:0为合格，1为不合格
     */
    public static MeasureDataVO type12(List<GroupPointVO> groupPoints, String rangeMath) {
        int totalPointNum = 0; //总点数
        int totalQFPointNum = 0; //总合格点数
        double qualifiedRate = 0.0d; //单项合格率
        MeasureDataVO dataMap = new MeasureDataVO();
        for (GroupPointVO gp : groupPoints) {
            for (PointVO p: gp.getGroupData()){
                //不需要偏差值 记为0
                p.setDeviation(0d);
                //把double类型转变为int类型，判断是否合格
                int i = new Double(p.getMeasureValue()).intValue();
                if (i==0){
                    gp.getQFPoint().add(p.getMeasureValue());
                }else {
                    gp.getDQFPoint().add(p.getMeasureValue());
                }
            }
            //计算总点数
            totalPointNum += gp.getGroupData().size();
            //计算总合格点数
            totalQFPointNum += gp.getQFPoint().size();
        }
        qualifiedRate = totalQFPointNum / totalPointNum;
        dataMap.setGroupPoints(groupPoints);
        dataMap.setQualifiedRate(qualifiedRate);
        dataMap.setTotalPointNum(totalPointNum);
        dataMap.setTotalQFPointNum(totalQFPointNum);
        return dataMap;
    }
}
